home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 376-400 / disk_386 / xlispstat / src2.lzh / XLisp-Stat / xsscatmat.c < prev    next >
C/C++ Source or Header  |  1990-10-04  |  15KB  |  509 lines

  1. /* xsscatmat - XLISP interface to IVIEW dynamic graphics package.      */
  2. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  3. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  4. /* You may give out copies of this software; for conditions see the    */
  5. /* file COPYING included with this distribution.                       */
  6.  
  7. #include "xlisp.h"
  8. #include "osdef.h"
  9. #ifdef ANSI
  10. #include "xlproto.h"
  11. #include "xlsproto.h"
  12. #include "iviewproto.h"
  13. #include "Stproto.h"
  14. #else
  15. #include "xlfun.h"
  16. #include "xlsfun.h"
  17. #include "iviewfun.h"
  18. #include "Stfun.h"
  19. #endif ANSI
  20. #include "xlsvar.h"
  21.  
  22. #ifdef ANSI
  23. void get_plot_layout(IVIEW_WINDOW,int *,int *,int *),
  24.      DrawLabel(IVIEW_WINDOW,int),find_current_plot(IVIEW_WINDOW,int,int),
  25.      ScatDrawPoint(IVIEW_WINDOW,int,PointState,PointState),
  26.      scat_draw_point(IVIEW_WINDOW,int,PointState),
  27.      find_current_plot(IVIEW_WINDOW,int,int);
  28. LVAL scatmat_add_data(int),iview_scatmat_mouse(int);
  29. #else
  30. void get_plot_layout(),
  31.      DrawLabel(),find_current_plot(),
  32.      ScatDrawPoint(),
  33.      scat_draw_point(),
  34.      find_current_plot();
  35. LVAL scatmat_add_data(),iview_scatmat_mouse();
  36. #endif ANSI
  37.  
  38. #define SCAT_PLOT_GAP 1
  39. #define SCAT_INSET 4
  40. #define LABEL_OFFSET 5
  41. #define MAX_NUM_VARS 10
  42.  
  43. #define VAR_FORMAT "var %d"
  44. #define POINT_FORMAT "%d"
  45.  
  46. static int pdata[MAX_NUM_VARS];
  47.  
  48. static struct {
  49.   int x, y, left, top, size, bottom;
  50. } current;
  51.  
  52. /**************************************************************************/
  53. /**                                                                      **/
  54. /**                        Plot Creation Functions                       **/
  55. /**                                                                      **/
  56. /**************************************************************************/
  57.  
  58. LVAL iview_scatmat_allocate()
  59. {  
  60.   LVAL object;
  61.   int i, vars, show;
  62.   IVIEW_WINDOW w;
  63.   char s[100];
  64.  
  65.   object = xlgaobject();
  66.   show = xsboolkey(sk_show, TRUE);
  67.   
  68.   get_iview_ivars(object, &vars);
  69.   if (vars < 2) xlfail("Too few variables for scatmat");
  70.   if (vars > MAX_NUM_VARS) xlfail("Too many variables for scatmat");
  71.   
  72.   w = IViewNew(object);
  73.   
  74.   /* should replace this by something lisp-based +++++++ */
  75.   for (i = 0; i < vars; i++) {
  76.     sprintf(s, VAR_FORMAT, i);
  77.     IViewSetVariableLabel(w, i, s);
  78.     IViewSetRange(w, i, 0.0, 1.0);
  79.   }
  80.   
  81.   initialize_iview(w, object);
  82.   /* use StShowWindow to show (map) window but NOT send :resize or :redraw */
  83.   if (show) StShowWindow(w);
  84.   return(object);
  85. }
  86.  
  87. /**************************************************************************/
  88. /**                                                                      **/
  89. /**                            Data Functions                            **/
  90. /**                                                                      **/
  91. /**************************************************************************/
  92.  
  93. static LVAL scatmat_add_data(which)
  94.      int which;
  95. {
  96.   IVIEW_WINDOW w;
  97.   LVAL data, object;
  98.   int old_n, n;
  99.   
  100.   object = xlgaobject();
  101.   w = GETIVIEWADDRESS(object);
  102.   if (w == nil) return(NIL);
  103.   data = xlgetarg();
  104.  
  105.   switch(which) {
  106.   case 'P':
  107.     old_n = IViewNumPoints(w);
  108.     internal_iview_add_points(w, object, data);
  109.     n = IViewNumPoints(w);
  110.     break;
  111.   case 'L':
  112.     old_n = IViewNumLines(w);
  113.     internal_iview_add_lines(w, object, data);
  114.     n = IViewNumLines(w);
  115.     break;
  116. #ifdef USESTRINGS
  117.   case 'S':
  118.     old_n = IViewNumStrings(w);
  119.     internal_iview_add_strings(w, object, data);
  120.     n = IViewNumStrings(w);
  121.     break;
  122. #endif /* USESTRINGS */
  123.   }
  124.   
  125.   check_add_to_screen(object, which, old_n, n, TRUE);
  126.   
  127.   return(NIL);
  128. }
  129.  
  130. LVAL iview_scatmat_add_points()  { return(scatmat_add_data('P')); }
  131. LVAL iview_scatmat_add_lines()   { return(scatmat_add_data('L')); }
  132. #ifdef USESTRINGS
  133. LVAL iview_scatmat_add_strings() { return(scatmat_add_data('S')); }
  134. #endif /* USESTRINGS */
  135.  
  136. /**************************************************************************/
  137. /**                                                                      **/
  138. /**                    Drawing and Resizing Functions                    **/
  139. /**                                                                      **/
  140. /**************************************************************************/
  141.  
  142. LVAL iview_scatmat_resize()
  143. {
  144.   int vars;
  145.   int i, top, left, subsize, low, high;
  146.   IVIEW_WINDOW w;
  147.   LVAL object;
  148.   
  149.   object = xlgaobject();
  150.   xllastarg();
  151.   
  152.   w = GETIVIEWADDRESS(object);
  153.   if (w == nil) return(NIL);
  154.   
  155.   vars = IViewNumVariables(w);
  156.   IViewSetFixedAspect(w, TRUE);
  157.   IViewStdResize(w);
  158.  
  159.   get_plot_layout(w, &left, &top, &subsize);
  160.  
  161.   for (i = 0; i < vars; i++) {
  162.     low = i * (subsize + SCAT_PLOT_GAP) + 2 * SCAT_INSET + SCAT_PLOT_GAP;
  163.     high = low + subsize - 3 * SCAT_INSET;
  164.     IViewSetScreenRange(w, i, low, high);
  165.   }
  166.   return(NIL);
  167. }
  168.  
  169. LVAL iview_scatmat_redraw_content()
  170. {
  171.   int vars;
  172.   int left, top, subleft, subtop, subsize;
  173.   int viewleft, viewtop, viewwidth, viewheight;
  174.   int i, j;
  175.   double low, high;
  176.   char s[100];
  177.   IVIEW_WINDOW w;
  178.   LVAL object, scale_type;
  179.   /* char */ StGWWinInfo *gwinfo; /* changed JKL */
  180.   
  181.   object = xlgaobject();
  182.   xllastarg();
  183.   
  184.   gwinfo = StGWObWinInfo(object);
  185.   w = GETIVIEWADDRESS(object);
  186.   if (w == nil) return(NIL);
  187.     
  188.   vars = IViewNumVariables(w);
  189.   if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
  190.   StGWGetViewRect(gwinfo, &viewleft, &viewtop, &viewwidth, &viewheight);
  191.   get_plot_layout(w, &left, &top, &subsize);
  192.   scale_type = slot_value(object, s_scale_type);
  193.  
  194.   StGWStartBuffering(gwinfo);
  195.   StGWEraseRect(gwinfo, viewleft, viewtop, viewwidth, viewheight);
  196.   for (i = 0; i < vars; i++) 
  197.     for (j = 0; j < vars; j++) {
  198.       subleft = left + j * (SCAT_PLOT_GAP + subsize);
  199.       subtop = top + (vars - i - 1) * (SCAT_PLOT_GAP + subsize);
  200.       StGWFrameRect(gwinfo, subleft, subtop, subsize, subsize);
  201.       if (i == j && scale_type == NIL) {
  202.         if (IViewVariableLabel(w, i) != 0)
  203.           StGWDrawText(gwinfo, IViewVariableLabel(w, i), 
  204.                        subleft + subsize / 2, subtop + subsize / 2, 1, 0);
  205.         IViewGetRange(w, i, &low, &high);
  206.         sprintf(s, "%.3lg", high);
  207.         StGWDrawText(gwinfo, s, 
  208.              subleft + subsize - SCAT_INSET,
  209.              subtop + SCAT_INSET, 2, 1);
  210.         sprintf(s, "%.3lg", low);
  211.         StGWDrawText(gwinfo, s, 
  212.              subleft + SCAT_INSET,
  213.              subtop + subsize - SCAT_INSET, 0, 0);
  214.       }
  215.       else if (i != j) {
  216.         IViewDrawDataPoints(w, i, j, 0, IViewNumPoints(w));
  217.         IViewDrawDataLines(w, i, j, 0, IViewNumLines(w));
  218. #ifdef USESTRINGS
  219.         IViewDrawDataStrings(w, i, j, 0, IViewNumStrings(w));
  220. #endif /* USESTRINGS */
  221.       }
  222.     }
  223.   StGWBufferToScreen(gwinfo, viewleft, viewtop, viewwidth, viewheight);
  224.   if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
  225.   IViewResetScreenStates(w);
  226.   return(NIL);
  227. }
  228.  
  229. /**************************************************************************/
  230. /**                                                                      **/
  231. /**                           Mouse Functions                            **/
  232. /**                                                                      **/
  233. /**************************************************************************/
  234.  
  235. /*extern LVAL peekarg(); in headers JKL */
  236.  
  237. static LVAL iview_scatmat_mouse(click)
  238.      int click;
  239. {
  240.   IVIEW_WINDOW w;
  241.   LVAL object;
  242.   int x, y;
  243.   
  244.   object = xlgaobject();
  245.   w = GETIVIEWADDRESS(object);
  246.  
  247.   if (w != nil) {
  248.     x = fixp(peekarg(0)) ? getfixnum(peekarg(0)) : 0;
  249.     y = fixp(peekarg(1)) ? getfixnum(peekarg(1)) : 0;
  250.     find_current_plot(w, x, y);
  251.     if (click) IViewDoClick(object);
  252.     else IViewDoMotion(object);
  253.   }
  254.   return(NIL);
  255. }
  256.  
  257. LVAL iview_scatmat_click() { return(iview_scatmat_mouse(TRUE)); }
  258. LVAL iview_scatmat_motion() { return(iview_scatmat_mouse(FALSE)); }
  259.  
  260. LVAL iview_scatmat_adjust_screen_point()
  261. {
  262.   LVAL object;
  263.   int point;
  264.   IVIEW_WINDOW w;
  265.   PointState state, screen_state;
  266.   
  267.   object = xlgaobject();
  268.   point = getfixnum(xlgafixnum());
  269.   xllastarg();
  270.  
  271.   w = GETIVIEWADDRESS(object);
  272.   if (w == nil) return(NIL);
  273.   
  274.   if (! IViewPointMasked(w, point)) {
  275.     state = IViewPointState(w, point);
  276.     screen_state = IViewPointScreenState(w, point);
  277.     if (state == pointInvisible || screen_state == pointInvisible) {
  278.       StGrSetDirty(StGWObWinInfo(object), TRUE);
  279.     }
  280.     else {
  281.       scat_draw_point(w, point, state);
  282.     }
  283.   }
  284.   
  285.   return(NIL);
  286. }
  287.  
  288. LVAL iview_scatmat_adjust_points_in_rect()
  289. {
  290.   int var1, var2, x, y, px, py;
  291.   int  i, n, in_rect, right, bottom, left, top, width, height;
  292.   PointState point_state, state;
  293.   IVIEW_WINDOW w;
  294.   LVAL object;
  295.   /* char*/ StGWWinInfo *gwinfo; /* changed JKL */
  296.   
  297.   object = xlgaobject();
  298.   w = GETIVIEWADDRESS(object);
  299.   left = getfixnum(xlgafixnum());
  300.   top = getfixnum(xlgafixnum());
  301.   width = getfixnum(xlgafixnum());
  302.   height = getfixnum(xlgafixnum());
  303.   state = decode_point_state(xlgetarg());
  304.   xllastarg();
  305.   
  306.   if (w == nil) return(NIL);
  307.   gwinfo = StGWObWinInfo(object);
  308.   
  309.   IViewCheckLinks(w);
  310.   n = IViewNumPoints(w);
  311.   bottom = top + height;
  312.   right = left + width;
  313.   StGrGetContentVariables(gwinfo, &var1, &var2);
  314.   StGrGetContentOrigin(gwinfo, &x, &y);
  315.   
  316.   if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
  317.  
  318.   for (i = 0; i < n; i++) {
  319.     point_state = IViewPointState(w, i);
  320.     if (! IViewPointMasked(w, i) && point_state != pointInvisible) {
  321.       px = x + IViewPointScreenValue(w, var1, i);
  322.       py = y - IViewPointScreenValue(w, var2, i);
  323.       in_rect = (var1 != var2 
  324.          && px >= left && px <= right && py >= top && py <= bottom);
  325.       if (in_rect && (int) point_state < (int) state) {
  326.         IViewSetPointState(w, i, state);
  327.       }
  328.       else if (! in_rect 
  329.            && state == pointHilited && point_state == pointHilited) {
  330.         IViewSetPointState(w, i, pointNormal);
  331.       }
  332.     }
  333.   }
  334.   IViewAdjustScreens(w);
  335.   if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
  336.   
  337.   return(NIL);
  338. }
  339.  
  340. LVAL iview_scatmat_mark_points_in_rect()
  341. {
  342.   int var1, var2;
  343.   int left, top, width, height;
  344.   IVIEW_WINDOW w;
  345.   LVAL object;
  346.   /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  347.   
  348.   object = xlgaobject();
  349.   w = GETIVIEWADDRESS(object);
  350.   left = getfixnum(xlgafixnum());
  351.   top = getfixnum(xlgafixnum());
  352.   width = getfixnum(xlgafixnum());
  353.   height = getfixnum(xlgafixnum());
  354.   xllastarg();
  355.   
  356.   if (w == nil) return(NIL);
  357.   gwinfo = StGWObWinInfo(object);
  358.   
  359.   StGrGetContentVariables(gwinfo, &var1, &var2);
  360.   if (var1 == var2)   IViewClearPointMarks(w);
  361.   else IViewStdMarkPointsInRect(w, left, top, width, height);
  362.   return(NIL);
  363. }
  364.  
  365. /**************************************************************************/
  366. /**                                                                      **/
  367. /**                          Internal Functions                          **/
  368. /**                                                                      **/
  369. /**************************************************************************/
  370.  
  371. static void get_plot_layout(w,subleft,subtop,subsize)
  372.      IVIEW_WINDOW w;
  373.      int *subleft, *subtop, *subsize;
  374. {
  375.   int vars, left, top, width, height, delta;
  376.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  377.  
  378.   vars = IViewNumVariables(w);
  379.   StGrGetContentRect(gwinfo, &left, &top, &width, &height);
  380.  
  381.   if (subleft != nil && subtop != nil && subsize != nil) {
  382.     *subsize = (width - SCAT_PLOT_GAP * (vars + 1)) / vars;
  383.     if (*subsize < 0) *subsize = 0;
  384.  
  385.     delta = (width - (vars * *subsize + (vars - 1) * SCAT_PLOT_GAP)) / 2;
  386.     if (delta < 0) delta = 0;
  387.  
  388.     *subleft = left + delta;
  389.     *subtop = top + delta;
  390.   }
  391. }
  392.  
  393. static void ScatDrawPoint(w, point, state, screen_state)
  394.     IVIEW_WINDOW w;
  395.     int point;
  396.     PointState state, screen_state;
  397. {
  398.   int vars = IViewNumVariables(w);
  399.   int left, bottom;
  400.   int oldwidth, oldheight, newwidth, newheight;
  401.   int i, j;
  402.   int x, y, oldsym, newsym, sym, hsym, replace;
  403.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  404.   ColorCode color, oldcolor, use_color = StGWUseColor(gwinfo);
  405.  
  406.   IViewGetPointSymbol(w, point, &sym, &hsym);
  407.   oldsym = (screen_state == pointNormal) ? sym : hsym;
  408.   newsym = (state == pointNormal) ? sym : hsym;
  409.   if (state == pointInvisible) return;
  410.   
  411.   StGWGetSymbolSize(oldsym, &oldwidth, &oldheight);
  412.   StGWGetSymbolSize(newsym, &newwidth, &newheight);
  413.   replace = (oldwidth > newwidth || oldheight > newheight);
  414.  
  415.   IViewGetScreenPointValues(w, point, pdata);
  416.  
  417.   StGrGetContentOrigin(gwinfo, &left, &bottom);
  418.   if (use_color) {
  419.     oldcolor = StGWDrawColor(gwinfo);
  420.     color = IViewPointColor(w, point);
  421.     if (color >= 0) StGWSetDrawColor(gwinfo, color);
  422.   }
  423.   for (i = 0; i < vars; i++) {
  424.     y = bottom - pdata[i];
  425.     for (j = 0; j < vars; j++)
  426.       if (i != j) {
  427.         x = left + pdata[j];
  428.         if (replace) StGWReplaceSymbol(gwinfo, oldsym, newsym, x, y);
  429.         else StGWDrawSymbol(gwinfo, newsym, x, y);
  430.       }
  431.   }
  432.   if (use_color && color >= 0) StGWSetDrawColor(gwinfo, oldcolor);
  433. }
  434.  
  435. static void DrawLabel(w, point)
  436.     IVIEW_WINDOW w;
  437.     int point;
  438. {
  439.   int vars = IViewNumVariables(w);
  440.   int left, bottom;
  441.   int i, j;
  442.   int x, y;
  443.   char *label;
  444.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  445.   int mode = StGWDrawMode(gwinfo);
  446.  
  447.   label = IViewPointLabel(w, point);
  448.   if (label == nil) return;
  449.     
  450.   for (i = 0; i < vars; i++) pdata[i] = IViewPointScreenValue(w, i, point);
  451.   StGrGetContentOrigin(gwinfo, &left, &bottom);
  452.   for (i = 0; i < vars; i++) {
  453.     y = bottom - pdata[i] - LABEL_OFFSET;
  454.     for (j = 0; j < vars; j++)
  455.       if (i != j) {
  456.         x = left + pdata[j] + LABEL_OFFSET;
  457.         StGWSetDrawMode(gwinfo, 1);
  458.         StGWDrawString(gwinfo, label, x, y);
  459.         StGWSetDrawMode(gwinfo, mode);
  460.       }
  461.   }
  462. }
  463.  
  464. static void find_current_plot(w, x, y)
  465.      IVIEW_WINDOW w;
  466.      int x, y;
  467. {
  468.   int width, height;
  469.   int left, top, subsize, vars;
  470.   /*char*/StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  471.   
  472.   vars = IViewNumVariables(w);
  473.   
  474.   if (IViewMouseMode(w) == brushing) {
  475.     IViewGetBrush(w, nil, nil, &width, &height);
  476.     x -= width / 2;
  477.     y -= height / 2;
  478.   }
  479.   
  480.   get_plot_layout(w, &left, &top, &subsize);
  481.   subsize += SCAT_PLOT_GAP;
  482.   current.x = (x - left) / subsize;
  483.   current.y = (top + vars * subsize - y - SCAT_PLOT_GAP) / subsize;
  484.   if (current.x < 0 || current.x >= vars 
  485.       || current.y < 0 || current.y >= vars) {
  486.     current.x = 0;
  487.     current.y = 0;
  488.   }
  489.   current.size = vars * subsize - SCAT_PLOT_GAP;
  490.   current.left = left;
  491.   current.top = top;
  492.   current.bottom = current.left + current.top + current.size;
  493.   StGrSetContentVariables(gwinfo, current.x, current.y);
  494. }
  495.  
  496. static void scat_draw_point(w, i, state)
  497.     IVIEW_WINDOW w;
  498.     int i;
  499.     PointState state;
  500. {
  501.   int showingLabels = IViewShowingLabels(w);
  502.   
  503.   if (state == pointNormal && showingLabels) DrawLabel(w, i); /* to erase */
  504.   ScatDrawPoint(w, i, state, state);
  505.   if (state != pointNormal && showingLabels) DrawLabel(w, i); /* to draw */
  506.   IViewSetPointScreenState(w, i, state);
  507. }
  508.  
  509.